package bignumber;

import java.math.BigDecimal;

/**
 * @author DCSGO
 * @version 1.0
 * 有极高的小数精度要求时可用
 * BigDecimal
 */
public class BigDecimal_ {
    public static void main(String[] args) {
        BigDecimal bigDecimal1 = new BigDecimal("10.1111998089867983482");
        System.out.println(bigDecimal1);//         10.1111998089867983482

        BigDecimal bigDecimal2 = new BigDecimal("3.14159265358979323846");
        System.out.println(bigDecimal2);//         3.14159265358979323846

        BigDecimal add = bigDecimal1.add(bigDecimal2);
        System.out.println(add);//13.25279246257659158666

        BigDecimal subtract = bigDecimal1.subtract(bigDecimal2);
        System.out.println(subtract);//6.96960715539700510974

        BigDecimal multiply = bigDecimal1.multiply(bigDecimal2);
        System.out.println(multiply);//31.765271038891446344756112983771856711772

        //其他与 BigInteger 差不多 但 divide(除法) 就有值得注意的地方了

        //BigDecimal divide = bigDecimal1.divide(bigDecimal2);//直接报错
        //ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
        //算数异常：没有终止小数扩张 (小数除不尽);没有可精确表示的小数结果

        System.out.println(bigDecimal1.divide(new BigDecimal("5")));//2.02223996179735966964

        //对于可能除不尽的情况(或避免JVM抛出异常) 就需要限制计算时的精度了
        BigDecimal divide = bigDecimal1.divide(bigDecimal2, BigDecimal.ROUND_CEILING);//计算结果的精度同被除数的小数位数
        System.out.println(divide);//3.2184948603801537607

        /*
         * Java中BigDecimal的divide方法有以下四个重载：
         *
         * divide(BigDecimal divisor): 将当前BigDecimal对象除以参数divisor，并返回商，采用RoundingMode.HALF_UP舍入模式。
         *
         * divide(BigDecimal divisor, int scale, RoundingMode roundingMode): 将当前BigDecimal对象除以参数divisor，并返回商，根据参数scale指定的小数位数保留结果，采用指定的舍入模式roundingMode。
         *
         * divide(BigDecimal divisor, int roundingMode): 将当前BigDecimal对象除以参数divisor，并返回商，采用指定的舍入模式roundingMode，但在此重载中无法指定小数位数。
         *
         * divide(BigDecimal divisor, int scale, int roundingMode): 将当前BigDecimal对象除以参数divisor，并返回商，根据参数scale指定的小数位数保留结果，采用指定的舍入模式roundingMode。
         *
         * 常见的舍入模式包括：
         *
         * RoundingMode.CEILING：向正无穷方向舍入
         * RoundingMode.DOWN：向零方向舍入
         * RoundingMode.FLOOR：向负无穷方向舍入
         * RoundingMode.HALF_DOWN：五舍六入
         * RoundingMode.HALF_EVEN：银行家舍入法（四舍六入，五无定向）
         * RoundingMode.HALF_UP：四舍五入
         * RoundingMode.UNNECESSARY：如果存在非零小数位则直接抛出ArithmeticException异常
         * RoundingMode.UP：向远离零的方向舍入
         */

        //精确到小数点后3位(四舍五入)
        divide = bigDecimal1.divide(bigDecimal2, 3, BigDecimal.ROUND_HALF_UP);
        System.out.println(divide);//3.218
    }
}
